#!/usr/bin/env python3
"""
ES Archive 基本使用示例

演示ES Archive的基本功能，包括备份、恢复、监控等。
"""

import os
import sys
from datetime import datetime, timezone, timedelta
from pathlib import Path

# 添加项目路径
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from es_archive.core.backup import BackupManager, BackupStrategy
from es_archive.core.restore import RestoreManager, RestoreStrategy
from es_archive.core.metadata import MetadataManager
from es_archive.utils.es_client import ESClient
from es_archive.utils.time_utils import TimeFieldDetector
from es_archive.monitoring.progress import ProgressMonitor
from es_archive.monitoring.metrics import MetricsCollector


def setup_es_client():
    """设置ES客户端"""
    config = {
        'hosts': [os.getenv('ES_HOST', 'localhost:9200')],
        'username': os.getenv('ES_USERNAME', 'elastic'),
        'password': os.getenv('ES_PASSWORD', 'password'),
        'timeout': 60
    }
    
    return ESClient(config)


def example_basic_backup():
    """示例：基本备份操作"""
    print("=== 基本备份示例 ===")
    
    # 创建ES客户端
    es_client = setup_es_client()
    
    # 创建备份管理器
    backup_config = {
        'batch_size': 1000,
        'compression': 'gzip',
        'parallel_workers': 4,
        'validate_data': True
    }
    backup_manager = BackupManager(es_client, backup_config)
    
    # 创建备份策略
    strategy = BackupStrategy(
        strategy_type="full",
        batch_size=1000,
        compression="gzip",
        validate_data=True
    )
    
    # 执行备份
    try:
        backup_metadata = backup_manager.backup_index(
            index="my_index",
            output_dir="./backups",
            strategy=strategy
        )
        
        print(f"✓ 备份完成")
        print(f"  备份ID: {backup_metadata.backup_id}")
        print(f"  备份路径: {backup_metadata.backup_path}")
        print(f"  文档数量: {backup_metadata.backed_up_documents}")
        print(f"  状态: {backup_metadata.status}")
        
        return backup_metadata.backup_id
        
    except Exception as e:
        print(f"✗ 备份失败: {e}")
        return None


def example_incremental_backup():
    """示例：增量备份"""
    print("\n=== 增量备份示例 ===")
    
    es_client = setup_es_client()
    backup_manager = BackupManager(es_client, {})
    
    # 增量备份策略（最近24小时）
    start_time = datetime.now(timezone.utc) - timedelta(hours=24)
    end_time = datetime.now(timezone.utc)
    
    strategy = BackupStrategy(
        strategy_type="incremental",
        time_field="@timestamp",
        time_range_start=start_time,
        time_range_end=end_time,
        batch_size=1000,
        compression="gzip"
    )
    
    try:
        backup_metadata = backup_manager.backup_index(
            index="my_index",
            output_dir="./backups",
            strategy=strategy
        )
        
        print(f"✓ 增量备份完成")
        print(f"  时间范围: {start_time} - {end_time}")
        print(f"  文档数量: {backup_metadata.backed_up_documents}")
        
        return backup_metadata.backup_id
        
    except Exception as e:
        print(f"✗ 增量备份失败: {e}")
        return None


def example_restore():
    """示例：数据恢复"""
    print("\n=== 数据恢复示例 ===")
    
    # 首先执行一个备份
    backup_id = example_basic_backup()
    if not backup_id:
        print("无法执行恢复，备份失败")
        return
    
    es_client = setup_es_client()
    
    # 创建恢复管理器
    restore_config = {
        'batch_size': 1000,
        'parallel_workers': 2,
        'validate_data': True
    }
    restore_manager = RestoreManager(es_client, restore_config)
    
    # 创建恢复策略
    strategy = RestoreStrategy(
        strategy_type="full",
        target_index="restored_index",
        create_index=True,
        overwrite_existing=False,
        validate_data=True
    )
    
    try:
        restore_metadata = restore_manager.restore_from_backup(
            backup_id=backup_id,
            strategy=strategy
        )
        
        print(f"✓ 恢复完成")
        print(f"  恢复ID: {restore_metadata.restore_id}")
        print(f"  目标索引: {restore_metadata.target_index}")
        print(f"  恢复文档: {restore_metadata.restored_documents}")
        print(f"  状态: {restore_metadata.status}")
        
    except Exception as e:
        print(f"✗ 恢复失败: {e}")


def example_time_field_detection():
    """示例：时间字段检测"""
    print("\n=== 时间字段检测示例 ===")
    
    es_client = setup_es_client()
    detector = TimeFieldDetector()
    
    try:
        # 获取索引映射
        mapping = es_client.get_mapping("my_index")
        
        # 检测时间字段
        time_fields = detector.detect_time_fields(mapping)
        print(f"检测到的时间字段: {time_fields}")
        
        # 建议最佳时间字段
        suggested = detector.suggest_time_field(mapping)
        print(f"建议使用的时间字段: {suggested}")
        
        # 分析时间字段质量
        if time_fields:
            for field in time_fields:
                quality = detector.analyze_time_field_quality("my_index", field, es_client)
                print(f"字段 {field} 质量分析:")
                print(f"  样本数量: {quality.get('sample_count', 0)}")
                print(f"  有效率: {quality.get('valid_rate', 0):.2%}")
                print(f"  时间范围: {quality.get('time_range', {})}")
        
    except Exception as e:
        print(f"✗ 时间字段检测失败: {e}")


def example_monitoring():
    """示例：监控和指标收集"""
    print("\n=== 监控示例 ===")
    
    # 使用进度监控器
    with ProgressMonitor() as monitor:
        # 创建进度跟踪器
        tracker = monitor.create_tracker(
            task_id="demo_task",
            total=100,
            description="演示任务"
        )
        
        # 模拟工作进度
        import time
        for i in range(100):
            # 模拟工作
            time.sleep(0.01)
            
            # 更新进度
            tracker.increment(custom_metrics={
                'processed_items': i + 1,
                'current_rate': (i + 1) / (time.time() - tracker.start_time)
            })
            
            # 每10步显示一次进度
            if (i + 1) % 10 == 0:
                progress = tracker.get_progress_info()
                print(f"  进度: {progress['percentage']:.1f}% "
                      f"(速度: {progress['rate']:.2f} items/sec)")
        
        print("✓ 任务完成")
    
    # 使用性能指标收集器
    print("\n性能指标收集:")
    with MetricsCollector(collection_interval=1.0) as collector:
        # 模拟一些工作
        time.sleep(2)
        
        # 添加自定义指标
        collector.increment_counter("documents_processed", 1000)
        collector.set_gauge("queue_size", 50)
        
        # 获取当前指标
        metrics = collector.get_current_metrics()
        print(f"  CPU使用率: {metrics.cpu_percent:.1f}%")
        print(f"  内存使用率: {metrics.memory_percent:.1f}%")
        print(f"  自定义指标: {metrics.custom_metrics}")


def example_metadata_management():
    """示例：元数据管理"""
    print("\n=== 元数据管理示例 ===")
    
    # 创建元数据管理器
    metadata_manager = MetadataManager("./metadata")
    
    try:
        # 列出所有备份
        backups = metadata_manager.list_backups()
        print(f"找到 {len(backups)} 个备份:")
        
        for backup in backups[:5]:  # 只显示前5个
            print(f"  - {backup.get('backup_id', 'unknown')[:20]}... "
                  f"({backup.get('source_index', 'unknown')}) "
                  f"[{backup.get('status', 'unknown')}]")
        
        # 按标签搜索
        tagged_backups = metadata_manager.list_backups(tags=['production'])
        print(f"\n生产环境备份: {len(tagged_backups)} 个")
        
        # 按状态过滤
        completed_backups = metadata_manager.list_backups(status='completed')
        print(f"已完成备份: {len(completed_backups)} 个")
        
    except Exception as e:
        print(f"✗ 元数据管理失败: {e}")


def example_error_handling():
    """示例：错误处理"""
    print("\n=== 错误处理示例 ===")
    
    from es_archive.utils.exceptions import (
        ESConnectionError, ESIndexNotFoundError, 
        BackupError, RestoreError
    )
    
    es_client = setup_es_client()
    
    try:
        # 尝试备份不存在的索引
        backup_manager = BackupManager(es_client, {})
        strategy = BackupStrategy(strategy_type="full")
        
        backup_manager.backup_index(
            index="nonexistent_index",
            output_dir="./backups",
            strategy=strategy
        )
        
    except ESIndexNotFoundError as e:
        print(f"✓ 正确捕获索引不存在错误: {e}")
        
    except ESConnectionError as e:
        print(f"✓ 正确捕获连接错误: {e}")
        
    except BackupError as e:
        print(f"✓ 正确捕获备份错误: {e}")
        print(f"  备份ID: {e.backup_id}")
        print(f"  原始错误: {e.original_error}")
        
    except Exception as e:
        print(f"✗ 未预期的错误: {e}")


def main():
    """主函数"""
    print("ES Archive 使用示例")
    print("=" * 50)
    
    # 检查ES连接
    try:
        es_client = setup_es_client()
        cluster_info = es_client.get_cluster_info()
        print(f"✓ ES连接成功: {cluster_info.get('cluster_name', 'unknown')}")
    except Exception as e:
        print(f"✗ ES连接失败: {e}")
        print("请确保Elasticsearch正在运行并且配置正确")
        return
    
    # 运行示例
    try:
        example_time_field_detection()
        example_basic_backup()
        example_incremental_backup()
        example_restore()
        example_monitoring()
        example_metadata_management()
        example_error_handling()
        
        print("\n" + "=" * 50)
        print("✓ 所有示例执行完成")
        
    except KeyboardInterrupt:
        print("\n用户中断执行")
    except Exception as e:
        print(f"\n✗ 示例执行失败: {e}")


if __name__ == "__main__":
    main()
